#include "CommandDesign.h"
#include <iostream>



using namespace std;

CommandInvoker::CommandInvoker()
= default;

CommandInvoker::~CommandInvoker()
{
	while (!CommandQueue.empty())
	{
		Command* cmd = CommandQueue.front();
		CommandQueue.pop();
		delete cmd;
		cmd = nullptr;
	}

	while (!undoQueue.empty())
	{
		Command* cmd = undoQueue.front();
		undoQueue.pop();
		delete cmd;
		cmd = nullptr;
	}

	commandMap.clear();
}

void CommandInvoker::execute(Command* cmd)
{
	cmd->execute();
	CommandQueue.push(cmd);
}

void CommandInvoker::execute(std::string cmd)
{
	if (commandMap.find(cmd) != commandMap.end())
	{
		commandMap[cmd]->execute();
		CommandQueue.push(commandMap[cmd]);
	}
	else
	{
		cout << "Command not found" << endl;
	}
}

void CommandInvoker::undo()
{
	if (!CommandQueue.empty())
	{
		Command* cmd = CommandQueue.front();
		CommandQueue.pop();
		cmd->undo();
		undoQueue.push(cmd);
	}
}

void CommandInvoker::undo(std::string cmd)
{
	if (commandMap.find(cmd) != commandMap.end())
	{
		commandMap[cmd]->undo();
		CommandQueue.push(commandMap[cmd]);
	}
	else
	{
		cout << "Command not found" << endl;
	}
}

void CommandInvoker::redo()
{
	if (!undoQueue.empty())
	{
		Command* cmd = undoQueue.front();
		undoQueue.pop();
		cmd->execute();
		CommandQueue.push(cmd);
	}
}

void CommandInvoker::redo(std::string cmd)
{
	if (commandMap.find(cmd) != commandMap.end())
	{
		commandMap[cmd]->execute();
		CommandQueue.push(commandMap[cmd]);
	}
	else
	{
		cout << "Command not found" << endl;
	}
}

void CommandInvoker::InsertCommand(std::string name, Command* cmdHandle)
{
	commandMap.insert(pair<string, Command*>(name, cmdHandle));
}

void PrintHelloCommand::execute()
{
	cout << "Hello" << endl;
}

void PrintHelloCommand::undo()
{
	cout << "Undo Hello" << endl;
}

void PrintWorldCommand::execute()
{
	cout << "World" << endl;
}

void PrintWorldCommand::undo()
{
	cout << "Undo World" << endl;
}

void PrintAddCommand::execute()
{
	cout << ma + mb << '\n';
}

void PrintAddCommand::undo()
{
	cout << "Undo Add" << '\n';
}
